package cn.com.open.itembank.controller;

import cn.com.open.itembank.common.GlobalConst;
import cn.com.open.itembank.common.enums.PaperImportType;
import cn.com.open.itembank.common.enums.SourceType;
import cn.com.open.itembank.dto.ImportParameter;
import cn.com.open.itembank.dto.PaperModel;
import cn.com.open.itembank.dto.ReturnModel;
import cn.com.open.itembank.dto.TestPaperSearchDto;
import cn.com.open.itembank.interceptor.Log;
import cn.com.open.itembank.service.ItemBankRemotePaperExportService;
import cn.com.open.itembank.service.ItemBankTestPaperRemoteService;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

/**
 * Created by lucky on 2017/7/13.
 */

/**
 * 试卷控制器
 */
@RestController
@RequestMapping("/itembank")
public class TestPaperController extends BaseController {
    private static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(TestPaperController.class);

    @Autowired
    private ItemBankTestPaperRemoteService service;
    @Autowired
    private ItemBankRemotePaperExportService itemBankPaperExportService;

    //region 新增相关（Create：理论方法 HttpPost）

    //region 新增试卷

    /**
     * 新增试卷
     *
     * @param request    the request
     * @param response   the response
     * @param itembankId 题库ID
     * @param paperModel 试卷主体模型
     */
    @Log(optType = "新增试卷", optDescription = "新增试卷，参数：%s", keyName = "paperModel")
    @RequestMapping(value = "/{itembankId}/paper", method = RequestMethod.POST)
    public void addPaper(HttpServletRequest request, HttpServletResponse response,
                         @PathVariable(value = "itembankId") String itembankId,
                         @RequestBody PaperModel paperModel) {

        String appKey = request.getHeader(appKeyString);
        ReturnModel model = service.addPaper(itembankId, paperModel, appKey);

        if (model.getCode() == GlobalConst.ID_NOT_EXIST) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else if (model.getCode() == GlobalConst.NO_PERMISSION) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        } else {
            responseJson(request, response, model.getData(), model.getMessage(), model.getCode());
        }
    }

    //endregion

    //region 复制试卷

    /**
     * 复制试卷
     * 历史接口：openapi/v3/Paper/{oldPid}/CopyTo/{newPid}
     *
     * @param request    the request
     * @param response   the response
     * @param itembankId 题库ID
     * @param oldId      旧试卷ID
     * @param newId      新试卷ID
     */
    @Log(optType = "复制试卷", optDescription = "复制试卷，ID：%s", keyName = "oldId")
    @PostMapping(value = "/{itembankId}/paper/{oldId}/copyto/{newId}")
    public void copyPaper(HttpServletRequest request, HttpServletResponse response,
                          @PathVariable(value = "itembankId") String itembankId,
                          @PathVariable(value = "oldId") String oldId,
                          @PathVariable(value = "newId") String newId) {

        String appKey = request.getHeader(appKeyString);
        ReturnModel model = service.copyTestPaper(itembankId, oldId, newId, appKey);

        if (model.getCode() == GlobalConst.ID_NOT_EXIST) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else if (model.getCode() == GlobalConst.NO_PERMISSION) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        } else {
            responseJson(request, response, model.getData(), model.getMessage(), model.getCode());
        }
    }

    //endregion

    //region 导入试卷

    /**
     * 导入试卷
     *
     * @param request     the request
     * @param response    the response
     * @param itembankId  题库id
     * @param importModel 试卷导入模型
     */
    @Log(optType = "导入试卷", optDescription = "导入试卷，ID：%s", keyName = "itembankId")
    @PostMapping(value = "/{itembankId}/paper/import")
    public void importPaper(HttpServletRequest request, HttpServletResponse response,
                            @PathVariable(value = "itembankId") String itembankId,
                            @RequestBody ImportParameter importModel) {

        String appkey = request.getHeader(appKeyString);
        importModel.setAppKey(appkey);
        importModel.setAppSecret(request.getHeader(appSecretString));
        importModel.setItemBankId(itembankId);
        importModel.setSourceType(SourceType.TESTPAPER);
        // 根据appkey的具体值判断内部或外部
        importModel.setSource(appkey == "c655762fdf5979cb382c94061d6ddebb" ? 0 : 1);

        ReturnModel model = itemBankPaperExportService.importPaper(itembankId, importModel);

        if (model.getCode() == GlobalConst.ID_NOT_EXIST) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else if (model.getCode() == GlobalConst.NO_PERMISSION) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        } else {
            responseJson(request, response, model.getData(), model.getMessage(), model.getCode());
        }
    }

    //endregion

    //endregion

    //region 删除相关（Delete：理论方法 HttpDelete）

    //region 删除试卷(默认删除是自动取消发布后删除)

    /**
     * 删除试卷(默认删除是自动取消发布后删除)
     *
     * @param request    the request
     * @param response   the response
     * @param itembankId 题库id
     * @param paperId    试卷ID
     * @return return model
     */
    @Log(optType = "删除试卷", optDescription = "删除试卷，默认删除是自动取消发布后删除，ID：%s", keyName = "paperId")
    @DeleteMapping(value = "/{itembankId}/paper/{paperId}/deleteauto")
    public void deleteAuto(HttpServletRequest request, HttpServletResponse response,
                           @PathVariable(value = "itembankId") String itembankId,
                           @PathVariable(value = "paperId") String paperId) {

        String appkey = request.getHeader(appKeyString);
        ReturnModel model = service.deleteAuto(itembankId, paperId, true, appkey);

        if (model.getCode() == GlobalConst.SUCCESS) {
            response.setStatus(HttpServletResponse.SC_NO_CONTENT);
        } else if (model.getCode() == GlobalConst.ID_NOT_EXIST) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else if (model.getCode() == GlobalConst.NO_PERMISSION) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        } else {
            responseJson(request, response, model.getData(), model.getMessage(), model.getCode());
        }
    }

    //endregion

    //region 删除试卷(不自动取消发布，故已发布的无法删除)

    /**
     * 删除试卷(不自动取消发布，故已发布的无法删除)
     *
     * @param request    the request
     * @param response   the response
     * @param itembankId 题库id
     * @param paperId    试卷ID
     * @return return model
     */
    @Log(optType = "删除试卷", optDescription = "删除试卷，不自动取消发布，故已发布的无法删除，ID：%s", keyName = "paperId")
    @DeleteMapping(value = "/{itembankId}/paper/{paperId}/redelete")
    public void redelete(HttpServletRequest request, HttpServletResponse response,
                         @PathVariable(value = "itembankId") String itembankId,
                         @PathVariable(value = "paperId") String paperId) {

        String appkey = request.getHeader(appKeyString);
        ReturnModel model = service.deleteAuto(itembankId, paperId, false, appkey);

        if (model.getCode() == GlobalConst.SUCCESS) {
            response.setStatus(HttpServletResponse.SC_NO_CONTENT);
        } else if (model.getCode() == GlobalConst.ID_NOT_EXIST) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else if (model.getCode() == GlobalConst.NO_PERMISSION) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        } else {
            responseJson(request, response, model.getData(), model.getMessage(), model.getCode());
        }
    }

    //endregion

    //endregion

    //region 更新相关（Update：理论方法 HttpPut）

    //region 修改试卷状态

    /**
     * 修改试卷状态
     *
     * @param request    the request
     * @param response   the response
     * @param itembankId 题库id
     * @param paperId    试卷id
     * @return the return model
     */
    @Log(optType = "修改试卷状态", optDescription = "修改试卷状态，ID：%s", keyName = "paperId")
    @RequestMapping(value = "/{itembankId}/paper/{paperId}/status", method = RequestMethod.PUT)
    public void updateStatusPaper(HttpServletRequest request, HttpServletResponse response,
                                  @PathVariable(value = "itembankId") String itembankId,
                                  @PathVariable(value = "paperId") String paperId) {

        String appkey = request.getHeader(appKeyString);
        ReturnModel model = service.updateStatus(itembankId, paperId, appkey);

        if (model.getCode() == GlobalConst.ID_NOT_EXIST) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else if (model.getCode() == GlobalConst.NO_PERMISSION) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        } else {
            responseJson(request, response, model.getData(), model.getMessage(), model.getCode());
        }
    }

    //endregion

    //region 修改试卷名称

    /**
     * 修改试卷名称
     *
     * @param request    the request
     * @param response   the response
     * @param itembankId 题库id
     * @param paperId    试卷id
     * @param paperName  试卷名称
     * @return the return model
     */
    @Log(optType = "修改试卷名称", optDescription = "修改试卷名称，ID：%s", keyName = "paperId")
    @RequestMapping(value = "/{itembankId}/paper/{paperId}/title", method = RequestMethod.PUT)
    public void updatePaperName(HttpServletRequest request, HttpServletResponse response,
                                @PathVariable(value = "itembankId") String itembankId,
                                @PathVariable(value = "paperId") String paperId,
                                @RequestParam("c") String paperName) {

        String appkey = request.getHeader(appKeyString);
        ReturnModel model = service.updateTestPaperName(itembankId, paperId, paperName, appkey);

        if (model.getCode() == GlobalConst.ID_NOT_EXIST) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else if (model.getCode() == GlobalConst.NO_PERMISSION) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        } else {
            responseJson(request, response, model.getData(), model.getMessage(), model.getCode());
        }
    }

    //endregion

    //region 发布试卷

    /**
     * 发布试卷
     *
     * @param request    the request
     * @param response   the response
     * @param itembankId 题库id
     * @param paperId    试卷id
     * @param publisher  发布人
     * @return the return model
     */
    @Log(optType = "发布试卷", optDescription = "发布试卷，ID：%s", keyName = "paperId")
    @PutMapping(value = "/{itembankId}/paper/{paperId}/release")
    public void releasePaper(HttpServletRequest request, HttpServletResponse response,
                             @PathVariable(value = "itembankId") String itembankId,
                             @PathVariable(value = "paperId") String paperId,
                             @RequestParam("publisher") String publisher) {

        String appKey = request.getHeader(appKeyString);
        ReturnModel model = service.testPaperRelease(itembankId, paperId, publisher, appKey);

        if (model.getCode() == GlobalConst.ID_NOT_EXIST) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else if (model.getCode() == GlobalConst.NO_PERMISSION) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        } else {
            responseJson(request, response, model.getData(), model.getMessage(), model.getCode());
        }
    }

    //endregion

    //region 取消发布试卷

    /**
     * 取消发布试卷
     *
     * @param request    the request
     * @param response   the response
     * @param itembankId 题库id
     * @param paperId    试卷id
     * @return the return model
     */
    @Log(optType = "取消发布试卷", optDescription = "取消发布试卷，ID：%s", keyName = "paperId")
    @PutMapping(value = "/{itembankId}/paper/{paperId}/cancelrelease")
    public void cancelReleasePaper(HttpServletRequest request, HttpServletResponse response,
                                   @PathVariable(value = "itembankId") String itembankId,
                                   @PathVariable(value = "paperId") String paperId) {

        String appKey = request.getHeader(appKeyString);
        ReturnModel model = service.cancelTestPaperRelease(itembankId, paperId, appKey);

        if (model.getCode() == GlobalConst.ID_NOT_EXIST) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else if (model.getCode() == GlobalConst.NO_PERMISSION) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        } else {
            responseJson(request, response, model.getData(), model.getMessage(), model.getCode());
        }
    }

    // endregion

    //endregion

    //region 查询相关（Retrieve：理论方法 HttpGet）

    //region 获取试卷完整信息

    /**
     * 获取试卷完整信息
     *
     * @param request    the request
     * @param response   the response
     * @param itembankId 题库id
     * @param paperId    试卷id
     * @return 试卷模型
     */
    @Log(optType = "获取试卷完整信息", optDescription = "获取试卷完整信息，ID：%s", keyName = "paperId")
    @RequestMapping(value = "/{itembankId}/paper/{paperId}", method = RequestMethod.GET)
    public void getFullPaper(HttpServletRequest request, HttpServletResponse response,
                             @PathVariable(value = "itembankId") String itembankId,
                             @PathVariable(value = "paperId") String paperId) {

        if (!isPermissionForItemBank(request, itembankId)) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return;
        }

        ReturnModel model = service.getFullPaper(itembankId, paperId);

        if (model.getCode() == GlobalConst.ID_NOT_EXIST) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else {
            responseJson(request, response, model.getData(), model.getMessage(), model.getCode());
        }
    }

    //endregion

    //region 获取试卷答案信息

    /**
     * 获取试卷答案信息
     *
     * @param request    the request
     * @param response   the response
     * @param itembankId 题库id
     * @param paperId    试卷id
     * @return 试卷答案模型
     */
    @Log(optType = "获取试卷答案信息", optDescription = "获取试卷答案信息，ID：%s", keyName = "paperId")
    @RequestMapping(value = "/{itembankId}/paper/{paperId}/answer", method = RequestMethod.GET)
    public void getPaperAnswer(HttpServletRequest request, HttpServletResponse response,
                               @PathVariable(value = "itembankId") String itembankId,
                               @PathVariable(value = "paperId") String paperId) {

        if (!isPermissionForItemBank(request, itembankId)) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return;
        }

        ReturnModel model = service.getPaperAnswer(itembankId, paperId);

        if (model.getCode() == GlobalConst.ID_NOT_EXIST) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else {
            responseJson(request, response, model.getData(), model.getMessage(), model.getCode());
        }
    }

    //endregion

    //region 获取试卷不含答案信息

    /**
     * 获取试卷不含答案信息
     *
     * @param request    the request
     * @param response   the response
     * @param itembankId 题库id
     * @param paperId    试卷id
     * @return 试卷答案模型
     */
    @Log(optType = "获取试卷不含答案信息", optDescription = "获取试卷不含答案信息，ID：%s", keyName = "paperId")
    @RequestMapping(value = "/{itembankId}/paper/{paperId}/withoutanswer", method = RequestMethod.GET)
    public void getPaperWithoutAnswer(HttpServletRequest request, HttpServletResponse response,
                                      @PathVariable(value = "itembankId") String itembankId,
                                      @PathVariable(value = "paperId") String paperId) {

        if (!isPermissionForItemBank(request, itembankId)) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return;
        }

        ReturnModel model = service.getPaperWithoutAnswer(itembankId, paperId);

        if (model.getCode() == GlobalConst.ID_NOT_EXIST) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else {
            responseJson(request, response, model.getData(), model.getMessage(), model.getCode());
        }
    }

    //endregion

    //region 获取试卷列表

    /**
     * 获取试卷列表
     *
     * @param request     the request
     * @param response    the response
     * @param itembankId  the item bank id
     * @param searchModel the searchModel
     * @return the paper list
     */
    @Log(optType = "获取试卷列表", optDescription = "获取试卷列表，参数：%s", keyName = "searchModel")
    @RequestMapping(value = "/{itembankId}/paper/list", method = RequestMethod.POST)
    public void getPaperList(HttpServletRequest request, HttpServletResponse response,
                             @PathVariable(value = "itembankId") String itembankId,
                             @RequestBody TestPaperSearchDto searchModel) {

        if (!isPermissionForItemBank(request, itembankId)) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return;
        }

        ReturnModel model = service.getPaperList(itembankId, searchModel);
        if (model.getCode() == GlobalConst.ID_NOT_EXIST) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else if (model.getCode() == GlobalConst.NO_PERMISSION) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        } else {
            responseJson(request, response, model.getData(), model.getMessage(), model.getCode());
        }
    }

    //endregion

    //region 导出试卷
    /**
     * 导出试卷
     *
     * @param request    the request
     * @param response   the response
     * @param itembankId 题库ID
     * @param paperId    试卷id
     * @param exportType 导出类型
     * @return return model
     */
    @Log(optType = "导出试卷", optDescription = "导出试卷，ID：%s", keyName = "paperId")
    @GetMapping(value = "/{itembankId}/paper/{paperId}/export")
    public void paperExportWord(HttpServletRequest request, HttpServletResponse response,
                                @PathVariable(value = "itembankId") String itembankId,
                                @PathVariable(value = "paperId") String paperId,
                                @RequestParam("exportType") Integer exportType) {

        String appKey = request.getHeader(appKeyString);
        ReturnModel model = itemBankPaperExportService.paperExportWord(itembankId, paperId, PaperImportType.fromValue(exportType), appKey);

        if (model.getCode() == GlobalConst.ID_NOT_EXIST) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else if (model.getCode() == GlobalConst.NO_PERMISSION) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        } else {
            responseJson(request, response, model.getData(), model.getMessage(), model.getCode());
        }
    }

    //endregion

    //region 导出试卷xml

    /**
     * 导出试卷xml
     * @return return model
     * @throws IOException the io exception
     */
    @Log(optType = "导出试卷xml", optDescription = "导出试卷xml，ID：%s", keyName = "itemBankId")
    @GetMapping(value = "/{itemBankId}/paper/export")
    public void exportPaperXML(HttpServletRequest request, HttpServletResponse response,
                                         @PathVariable(value = "itemBankId") String itemBankId) throws IOException {

        String appKey = request.getHeader(appKeyString);
        ReturnModel model = itemBankPaperExportService.exportPaperXML(itemBankId, appKey);
        if (model.getCode() == GlobalConst.ID_NOT_EXIST) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else if (model.getCode() == GlobalConst.NO_PERMISSION) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        } else {
            //二进制
            byte[] ff = getBytesByFile(model.getData().toString());
            //转化成base64字符串
            model.setData(Base64.encodeBase64String(ff));
            responseJson(request, response, model.getData().toString(), model.getMessage(), model.getCode());

            //测试
            //getFile(Base64.encodeBase64String(ff),"F:\\testUpload","text.zip");
        }
    }


    /**
     * 转化成byte[]数组
     */
    public static byte[] getBytesByFile(String pathStr) throws IOException {
        File f = new File(pathStr);
        try(ByteArrayOutputStream os = new ByteArrayOutputStream((int)f.length());
            BufferedInputStream fis = new BufferedInputStream(new FileInputStream(f))) {
            byte[] buff = new byte[3072];
            int size;
            while ((size = fis.read(buff)) != -1) {
                os.write(buff, 0, size);
            }
            return os.toByteArray();
        }
    }


    /**
     * 本地测试用
     * 根据byte数组，生成文件
     */
    public static void getFile(String s, String filePath,String fileName) {
        byte[] bfile = Base64.decodeBase64(s);
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            File dir = new File(filePath);
            if(!dir.exists()&&dir.isDirectory()){//判断文件目录是否存在
                dir.mkdirs();
            }
            file = new File(filePath+"\\"+fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bfile);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
    //endregion

    //endregion
}
